/**********************************************************************************************************************
 *
 * Project:    mGameEngine
 * File:       joint.h
 * Author:     twoja stara
 * Created on: 2009-09-24
 *
 **********************************************************************************************************************/

#ifndef JOINT_H_
#define JOINT_H_

#include "../common.h"
#include <NxPhysics.h>

namespace mGameEngine
{
namespace Physics
{

// prototype
class Actor;

/**
 * Base class for joints between actors.
 * Each joint connects exactly two different actors.
 * Joint ends are attached to actors anchors - frames specified
 * in actors local space.
 */
class Joint
{
protected:
    /**
     * First actor.
     */
    Actor *_actor1;

    /**
     * Second actor.
     */
    Actor *_actor2;

    /**
     * First actor anchor.
     */
    Matrix4x4 _anchor1;

    /**
     * Second actor anchor.
     */
    Matrix4x4 _anchor2;

    /**
     * Joint created.
     */
    mutable bool _created;

    /**
     * Physx joint.
     */
    mutable NxJoint *_joint;

public:
    /**
     * Create joint.
     */
    Joint();

    /**
     * Destroy joint.
     */
    virtual ~Joint();

    /**
     * Get first actor connected by joint.
     * @return first actor or NULL if joint connects to environment.
     */
    Actor *getFirstActor() const
    {
        return _actor1;
    }

    /**
     * Set first actor connected to joint.
     * @param actor actor.
     */
    void setFirstActor(Actor *actor);

    /**
     * Get second actor connected by joint.
     * @return second actor or NULL if joint connects to environment.
     */
    Actor *getSecondActor() const
    {
        return _actor2;
    }

    /**
     * Set second actor connected to joint.
     * @param actor actor.
     */
    void setSecondActor(Actor *actor);

    /**
     * Get joint first actor anchor.
     * @return joint first actor anchor.
     */
    const Matrix4x4 &getFirstActorAnchor() const
    {
        return _anchor1;
    }

    /**
     * Set joint first actor anchor.
     * @param anchor anchor.
     */
    virtual void setFirstActorAnchor(const Matrix4x4 &anchor);

    /**
     * Get joint second actor anchor.
     * @return joint second actor anchor.
     */
    const Matrix4x4 &getSecondActorAnchor() const
    {
        return _anchor2;
    }

    /**
     * Set joint second actor anchor.
     * @param anchor anchor.
     */
    virtual void setSecondActorAnchor(const Matrix4x4 &anchor);

    /**
     * Check if joint is already created.
     * @return true if joint is created, false otherwise.
     */
    bool isCreated() const
    {
        return _created;
    }

    /**
     * Create PhysX joint between two PhysX actors.
     * @param actor1 first PhysX actor.
     * @param actor2 second PhysX actor.
     */
    virtual void create(NxActor *actor1, NxActor *actor2) const = 0;
};

}
}

#endif // JOINT_H_
